﻿<cfscript>
/** 
* Security Frameworks - Access Granting Ticket Cookie
*
* @hint "Security Protocol. access-granting-ticket cookie" 
*/

component 
	displayname="public.service.ticket.accessGrantingCookie" 
	output=false 
	accessors=true 
	{
	
	property type="string" name="Key" hint="加密字符串";
	
	property name="ClientSession" hint="Cookie 操作组件";

	property type="string" name="AppId" hint="使用会话的应用程序名";
	property type="string" name="Domain" hint="会话的作用域";
	property type="string" name="Path" hint="会话的作用路径";
	
	property type="boolean" name="Secured" hint="是否要求使用 HTTPS 协议";
	property type="boolean" name="HttpOnly" hint="是否只可用于 HTTP/HTTPS 服务端";

	/**
	* @hint "初始化对象"
	* 
	* @appId "使用会话的应用程序名"
	* @domainName "会话的作用域"
	* @domainPath "会话的作用路径"
	* @requireSSL "是否要求使用 HTTPS 协议"
	* @httpOnly "是否只可用于 HTTP/HTTPS 服务端"
	*/
	public function init( required string appId, string domainName="", string domainPath="", boolean requireSSL=false, boolean httpOnly=true, required string encriptKey ) output=false {
		
		setAppId( arguments.appId );
		setDomain( arguments.domainName );
		setPath( arguments.domainPath );

		setSecured( arguments.requireSSL );
		setHttpOnly( arguments.httpOnly );
		
		setKey( arguments.encriptKey );
		
		return this;
	}
	
	/**
	* @hint "加密 Cookie String"
	*/
	public string function encryptTicket( required string inputString ) output=false {
		
		try {
			return encrypt( arguments.inputString, getKey() );
		}
		catch ( any exception ) {
			return "";
		}
		
	}
	
	/**
	* @hint "解密 Cookie String"
	*/
	public string function decryptTicket( required string inputString ) output=false {
		
		try {
			return decrypt( arguments.inputString, getKey() );
		}
		catch ( any exception ) {
			return "";
		}
		
	}
	
	/**
	* @hint "创建新的 Ticket-Granting Cookie"
	* 
	* @userId "单点认证的用户名"
	*/
	public void function create( required string userId ) output=false {
		
		/* 将 ATGC 记录在 Cookie 信息中 */
		var clientSession = getClientSession();
		
		clientSession.create( 
								name=getAppId(), 
								domain=getDomain(), path=getPath(), 
								secure=getSecured(), httponly=getHttpOnly(), 
								value="ATGC-" & encryptTicket( arguments.userId )
								);
		
	}
	
	/**
	* @hint "删除 Ticket-Granting Cookie"
	*/
	public void function delete() output=false {
		
		clientSession.expires(
								name=getAppId(), 
								domain=getDomain(), path=getPath()
								);
		
	}

	/**
	* @hint "从指定的 ATGC-ID 读取缓存内容, 并返回已认证用户名"
	*/
	public string function getUserName() output=false {
		
		if ( structKeyExists( cookie, getAppId() ) and left( cookie[getAppId()], 5 ) eq "ATGC-" ) {
			
			var userId = decryptTicket( listLast( cookie[getAppId()] , "-") );
			
			return userId;
		}
		
		return "";
	}
	
	/**
	* @hint "ATGC-ID 是否存在"
	*/
	public boolean function exists() {
		
		if ( len(getUserName()) ) { 
			return true;
		}
		else {
			delete();
		}
		
		return false;
	}
	
}

</cfscript>